/* eslint-disable @typescript-eslint/ban-ts-ignore */
/* eslint-disable @typescript-eslint/no-explicit-any */

import axios, { AxiosInstance } from 'axios';
import { Toast } from 'vant';
import { loading } from './loading';

type Params<T> = T extends (payload: infer P) => any ? P : void;
type TransformApiToAjax<A> = {
  // @ts-ignore
  [K in keyof A]: (params: Params<A[K]>) => ReturnType<A[K]>['response'];
};

// TODO: npm
function createApiCreator(request: any) {
  return function bindAxiosFunc<Api>(api: Api) {
    const funcNames = Object.keys(api as any);
    const obj = funcNames.reduce((pre, cur) => {
      pre[cur] = (params: any) => {
        // @ts-ignore
        const option = api[cur](params);
        return request(option);
      };
      return pre;
    }, {} as any);
    return obj as TransformApiToAjax<Api>;
  };
}

// TODO: npm
function axiosAdaptor(axiosInstant: AxiosInstance) {
  return function(option: any) {
    const { url, method, body } = option;
    if (method === 'GET') {
      return axiosInstant.get(url);
    }
    if (method === 'POST') {
      return axiosInstant.post(url, body);
    }

    console.error(`axios 适配器请求方法不支持:${method}`);
    return new Error('axiosAdaptor request method not support');
  };
}

const ax = axios.create({
  headers: {
    from: 'lxzs',
    partner: 'LAO_SI_JI',
    authorization: 'fQLbwBkER5a0DGAN4knGhQ5TV5xc4td3',
  },
});

ax.interceptors.request.use(v => {
  loading.add();
  return v;
});

ax.interceptors.response.use(
  response => {
    loading.sub();
    return response.data;
  },
  err => {
    loading.reset();
    const msg = err?.response?.data?.message;
    msg && Toast(msg);
    throw err;
  },
);

const request = axiosAdaptor(ax);
export const apiCreator = createApiCreator(request);
